package com.design.util;


import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * @author lijiaming
 * @version 1.0
 * @description  集合分组
 * @date 2025/10/29 10:47
 */
public class ListUtil {

    /**
     * 拆分集合数据，避免CPU内存处理不过来
     * 使用方式：
     * ListUtil.fixedGrouping(message, 10).forEach(v->{
     *                     String data = v.toString();
     *                     logger.info("sendTradeChargeNotice to mq, {}", data);
     *                     CommonMqQueueProperties properties = rabbitMQQueueProperties.getQueueMap().get(MQConstants.TRADE_CHARGE_NOTICE_QUEUQE);
     *                     rabbitTemplate.convertAndSend(
     *                             properties.getExchangeName(),
     *                             properties.getDelayQueueRoutingKey(),
     *                             data);
     *                 });
     */

    /**
     * 将一组数据固定分组，每组n个元素
     *
     * @param source 要分组的数据源
     * @param n      每组n个元素
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> fixedGrouping(List<T> source, int n) {

        if (null == source || source.size() == 0 || n <= 0)
            return null;
        List<List<T>> result = new ArrayList<List<T>>();
        int remainder = source.size() % n;
        int size = (source.size() / n);
        for (int i = 0; i < size; i++) {
            List<T> subset = null;
            subset = source.subList(i * n, (i + 1) * n);
            result.add(subset);
        }
        if (remainder > 0) {
            List<T> subset = null;
            subset = source.subList(size * n, size * n + remainder);
            result.add(subset);
        }
        return result;
    }

    /**
     * 读取的excel拆分
     *
     * @param excelData
     * @return
     */
    public static List<Map<Integer, Map<Integer, String>>> splitData(Map<Integer, Map<Integer, String>> excelData) {
        if (CollectionUtils.isEmpty(excelData)) {
            return null;
        }
        List<Map<Integer, Map<Integer, String>>> records = new LinkedList<>();
        Map<Integer, Map<Integer, String>> little = new HashMap<>();
        for (Map.Entry<Integer, Map<Integer, String>> excelEntry : excelData.entrySet()) {
            Integer key = excelEntry.getKey();
            Map<Integer, String> value = excelEntry.getValue();
            if (little.size() < 10) {
                little.put(key, value);
            } else {
                records.add(little);
                little = new HashMap<>();
                little.put(key, value);
            }
        }
        records.add(little);
        return records;
    }


    /**
     * List Stream API根据指定字段去重
     * putIfAbsent() 方法是
     *      如果 key对应的value值不存在, key value 添加到 map 中,并返回 null
     *      如果 key对应的value值已存在, key value 不再添加到 map 中, 并返回原 value
     *filter接收到结果为false的Predicate并将该值过滤掉
     * @param keyExtractor
     * @param <T>
     * @return
     */
    public static <T> Predicate<T> distinctByVariable(Function<? super T, ?> keyExtractor) {
        HashMap<Object, Boolean> map = new HashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}
